/*
 * Copyright 2005-2013 finalist.cn. All rights reserved.
 * Support: http://www.finalist.cn
 * License: http://www.finalist.cn/license
 */
package com.finalist.dao.impl;

import java.math.BigDecimal;
import java.util.Collections;
import java.util.Date;
import java.util.List;

import javax.persistence.FlushModeType;
import javax.persistence.LockModeType;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Repository;

import com.finalist.Filter;
import com.finalist.Page;
import com.finalist.Pageable;
import com.finalist.dao.OrderDao;
import com.finalist.entity.Member;
import com.finalist.entity.Order;
import com.finalist.entity.OrderItem;
import com.finalist.entity.Product;
import com.finalist.entity.Order.OrderStatus;
import com.finalist.entity.Order.PaymentStatus;
import com.finalist.entity.Order.ShippingStatus;

/**
 * Dao - 订单
 * 
 * @author Finalist IT Group
 * @version 3.0
 */
@Repository("orderDaoImpl")
public class OrderDaoImpl extends BaseDaoImpl<Order, Long> implements OrderDao {
    private static final Log log = LogFactory.getLog(OrderDaoImpl.class);

	public Order findBySn(String sn) {
		if (sn == null) {
			return null;
		}
		String jpql = "select orders from Order orders where lower(orders.sn) = lower(:sn)";
		try {
			return entityManager.createQuery(jpql, Order.class)
					.setFlushMode(FlushModeType.COMMIT).setParameter("sn", sn)
					.getSingleResult();
		} catch (Exception e) {
        	e.printStackTrace();
        	log.error(e.toString());
			return null;
		}
	}

	@Override
	public Page<Order> findPageByOrderName(Member member, String name,
			Pageable pageable) {
		return null;
		/*
		 * if (name == null) { return null; } String jpql =
		 * "select * from xx_order where id in(select orders  from xx_order_item where name like '%:name%')"
		 * ; try {
		 * 
		 * return entityManager.createQuery(jpql, Order.class)
		 * .setFlushMode(FlushModeType.COMMIT).setParameter("name", name)
		 * .getSingleResult(); } catch (NoResultException e) { return null; }
		 */
	}

	public List<Order> findList(Member member, Integer count,
			List<Filter> filters, List<com.finalist.Order> orders) {
		if (member == null) {
			return Collections.<Order> emptyList();
		}
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		criteriaQuery.where(criteriaBuilder.equal(root.get("member"), member));
		return super.findList(criteriaQuery, null, count, filters, orders);
	}

	public Page<Order> findPage(Member member, Pageable pageable) {
		if (member == null) {
			return new Page<Order>(Collections.<Order> emptyList(), 0, pageable);
		}
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
//		criteriaQuery.where(criteriaBuilder.equal(root.get("member"), member));
//		criteriaQuery.where(criteriaBuilder.equal(root.get("isEffective"),
//				true));
		Predicate restrictions = criteriaBuilder.conjunction();
		if (member != null) {
			restrictions = criteriaBuilder.equal(root.get("member"), member);
		}
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.equal(root.get("isEffective"), true));
		
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	public Page<Order> findPage(Member member, PaymentStatus paymentStatus,
			Pageable pageable) {
		if (member == null) {
			return new Page<Order>(Collections.<Order> emptyList(), 0, pageable);
		}
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		criteriaQuery.where(criteriaBuilder.equal(root.get("member"), member));
		criteriaQuery.where(criteriaBuilder.equal(root.get("paymentStatus"),
				paymentStatus));
		return super.findPage(criteriaQuery, pageable);

	}

	public Page<Order> findPageByStatue(Member member, Integer statue,
			Pageable pageable) {
		if (member == null) {
			return new Page<Order>(Collections.<Order> emptyList(), 0, pageable);
		}

		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		if (!statue.equals(0)) {// 非查询全部订单
			if (statue.equals(1)) {// 等待付款
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.notEqual(root.get("orderStatus"),
								OrderStatus.completed), criteriaBuilder
								.notEqual(root.get("orderStatus"),
										OrderStatus.cancelled));
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.or(
								criteriaBuilder.equal(
										root.get("paymentStatus"),
										PaymentStatus.unpaid), criteriaBuilder
										.equal(root.get("paymentStatus"),
												PaymentStatus.partialPayment)));
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.or(root
								.get("expire").isNull(), criteriaBuilder
								.greaterThanOrEqualTo(
										root.<Date> get("expire"), new Date())));
			} else if (statue.equals(2)) {// 等待发货
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.notEqual(root.get("orderStatus"),
								OrderStatus.completed), criteriaBuilder
								.notEqual(root.get("orderStatus"),
										OrderStatus.cancelled), criteriaBuilder
								.equal(root.get("paymentStatus"),
										PaymentStatus.paid), criteriaBuilder
								.equal(root.get("shippingStatus"),
										ShippingStatus.unshipped));
			} else if (statue.equals(3)) {// 等待收货
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.equal(root.get("paymentStatus"),
								PaymentStatus.paid));
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.notEqual(root.get("orderStatus"),
								OrderStatus.cancelled));
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.notEqual(root.get("orderStatus"),
								OrderStatus.completed));
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.equal(root.get("shippingStatus"),
								ShippingStatus.shipped));
			} else if (statue.equals(4)) {// 已完成
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.equal(root.get("orderStatus"),
								OrderStatus.completed));
			} else if (statue.equals(5)) {// 已取消
											// 订单未完成未取消的前提下:支付状态为未支付或者部分支付且过期日期不能为空且已经过期

				// 订单未完成未取消的前提
//				restrictions = criteriaBuilder.and(criteriaBuilder.notEqual(
//						root.get("orderStatus"), OrderStatus.cancelled),
//						criteriaBuilder.notEqual(root.get("orderStatus"),
//								OrderStatus.completed));

				// 过期
//				restrictions = criteriaBuilder.and(restrictions,
//						criteriaBuilder.lessThan(root.<Date> get("expire"),
//								new Date()), root.get("expire").isNotNull());

				// 部分支付或者未支付
				restrictions = criteriaBuilder.and(restrictions,
						criteriaBuilder.or(criteriaBuilder.equal(
								root.get("paymentStatus"),
								PaymentStatus.partialPayment), criteriaBuilder
								.equal(root.get("paymentStatus"),
										PaymentStatus.unpaid)));

				// 或者订单状态为取消状态
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
						.equal(root.get("orderStatus"), OrderStatus.cancelled));
			}else if(statue.equals(6)){//已过期订单
				restrictions = criteriaBuilder.and(restrictions,criteriaBuilder.or(
						criteriaBuilder.equal(root.get("paymentStatus"),PaymentStatus.unpaid),
						criteriaBuilder.equal(root.get("paymentStatus"), PaymentStatus.partialPayment)
																					)
													);//没支付或者部分支付
				
				
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
						.lessThan(root.<Date> get("expire"), new Date()));//已过期 
				restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
						.notEqual(root.get("orderStatus"), OrderStatus.cancelled));
								
				
//				restrictions = criteriaBuilder
//						.and(restrictions, criteriaBuilder.or(root
//								.get("expire").isNull(), criteriaBuilder
//								.lessThan(
//										root.<Date> get("expire"), new Date())));
			}
		}

		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);

	}

	public Page<Order> findPage(OrderStatus orderStatus, String productName,
			PaymentStatus paymentStatus, ShippingStatus shippingStatus,
			Boolean hasExpired, Long adminId,Pageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (orderStatus != null) {
			restrictions = criteriaBuilder
					.and(restrictions, criteriaBuilder.equal(
							root.get("orderStatus"), orderStatus));
		}
		if (productName != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("productName"), productName));
		}
		if (paymentStatus != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("paymentStatus"), paymentStatus));
		}
		if(adminId!=null){
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("adminId"), adminId));
		}
		if (shippingStatus != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("shippingStatus"), shippingStatus));
		}
		if (hasExpired != null) {
			if (hasExpired) {
				restrictions = criteriaBuilder.and(restrictions,
						root.get("expire").isNotNull(),
						criteriaBuilder.lessThan(root.<Date> get("expire"),
								new Date()));
			} else {
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.or(root
								.get("expire").isNull(), criteriaBuilder
								.greaterThanOrEqualTo(
										root.<Date> get("expire"), new Date())));
			}
		}
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.equal(root.get("isEffective"), true));
		
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	public Long count(OrderStatus orderStatus, PaymentStatus paymentStatus,
			ShippingStatus shippingStatus, Boolean hasExpired) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (orderStatus != null) {
			restrictions = criteriaBuilder
					.and(restrictions, criteriaBuilder.equal(
							root.get("orderStatus"), orderStatus));
		}
		if (paymentStatus != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("paymentStatus"), paymentStatus));
		}
		if (shippingStatus != null) {
			restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
					.equal(root.get("shippingStatus"), shippingStatus));
		}
		if (hasExpired != null) {
			if (hasExpired) {
				restrictions = criteriaBuilder.and(restrictions,
						root.get("expire").isNotNull(),
						criteriaBuilder.lessThan(root.<Date> get("expire"),
								new Date()));
			} else {
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.or(root
								.get("expire").isNull(), criteriaBuilder
								.greaterThanOrEqualTo(
										root.<Date> get("expire"), new Date())));
			}
		}
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	public Page<Order> findPageBywaitingPayment(Member member, Pageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.completed),
				criteriaBuilder.notEqual(root.get("orderStatus"),
						OrderStatus.cancelled));
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(
				criteriaBuilder.equal(root.get("paymentStatus"),
						PaymentStatus.unpaid),
				criteriaBuilder.equal(root.get("paymentStatus"),
						PaymentStatus.partialPayment)));
		restrictions = criteriaBuilder.and(
				restrictions,
				criteriaBuilder.or(
						root.get("expire").isNull(),
						criteriaBuilder.greaterThanOrEqualTo(
								root.<Date> get("expire"), new Date())));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	public Page<Order> findPageBywaitingShipping(Member member,
			Pageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.completed),
				criteriaBuilder.notEqual(root.get("orderStatus"),
						OrderStatus.cancelled), criteriaBuilder.equal(
						root.get("paymentStatus"), PaymentStatus.paid),
				criteriaBuilder.equal(root.get("shippingStatus"),
						ShippingStatus.unshipped));
		restrictions = criteriaBuilder.and(
				restrictions,
				criteriaBuilder.or(
						root.get("expire").isNull(),
						criteriaBuilder.greaterThanOrEqualTo(
								root.<Date> get("expire"), new Date())));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	@Override
	public Page<Order> findPageByOrderSn(Member member, String contentStr,
			Pageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions,
				criteriaBuilder.equal(root.get("sn"), contentStr));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	public Long waitingPaymentCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.completed),
				criteriaBuilder.notEqual(root.get("orderStatus"),
						OrderStatus.cancelled));
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(
				criteriaBuilder.equal(root.get("paymentStatus"),
						PaymentStatus.unpaid),
				criteriaBuilder.equal(root.get("paymentStatus"),
						PaymentStatus.partialPayment)));
		restrictions = criteriaBuilder.and(
				restrictions,
				criteriaBuilder.or(
						root.get("expire").isNull(),
						criteriaBuilder.greaterThanOrEqualTo(
								root.<Date> get("expire"), new Date())));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	public Long waitingShippingCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.completed),
				criteriaBuilder.notEqual(root.get("orderStatus"),
						OrderStatus.cancelled), criteriaBuilder.equal(
						root.get("paymentStatus"), PaymentStatus.paid),
				criteriaBuilder.equal(root.get("shippingStatus"),
						ShippingStatus.unshipped));
		restrictions = criteriaBuilder.and(
				restrictions,
				criteriaBuilder.or(
						root.get("expire").isNull(),
						criteriaBuilder.greaterThanOrEqualTo(
								root.<Date> get("expire"), new Date())));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	@Override
	public Long allOrderCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	public BigDecimal getSalesAmount(Date beginDate, Date endDate) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<BigDecimal> criteriaQuery = criteriaBuilder
				.createQuery(BigDecimal.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(criteriaBuilder.sum(root
				.<BigDecimal> get("amountPaid")));
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("orderStatus"), OrderStatus.completed));
		if (beginDate != null) {
			restrictions = criteriaBuilder.and(
					restrictions,
					criteriaBuilder.greaterThanOrEqualTo(
							root.<Date> get("createDate"), beginDate));
		}
		if (endDate != null) {
			restrictions = criteriaBuilder.and(
					restrictions,
					criteriaBuilder.lessThanOrEqualTo(
							root.<Date> get("createDate"), endDate));
		}
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery)
				.setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}

	public Integer getSalesVolume(Date beginDate, Date endDate) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Integer> criteriaQuery = criteriaBuilder
				.createQuery(Integer.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(criteriaBuilder.sum(root.join("orderItems")
				.<Integer> get("shippedQuantity")));
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("orderStatus"), OrderStatus.completed));
		if (beginDate != null) {
			restrictions = criteriaBuilder.and(
					restrictions,
					criteriaBuilder.greaterThanOrEqualTo(
							root.<Date> get("createDate"), beginDate));
		}
		if (endDate != null) {
			restrictions = criteriaBuilder.and(
					restrictions,
					criteriaBuilder.lessThanOrEqualTo(
							root.<Date> get("createDate"), endDate));
		}
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery)
				.setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}

	public List<Order> releaseStock() {
		String jpql = "select orders from Order orders where orders.isAllocatedStock = :isAllocatedStock and orders.expire is not null and orders.expire <= :now";
		List<Order> orders = entityManager.createQuery(jpql, Order.class)
				.setParameter("isAllocatedStock", true)
				.setParameter("now", new Date()).getResultList();
		if (orders != null) {
			for (Order order : orders) {
				if (order != null && order.getOrderItems() != null) {
					for (OrderItem orderItem : order.getOrderItems()) {
						if (orderItem != null) {
							Product product = orderItem.getProduct();
							if (product != null) {
								entityManager.lock(product,
										LockModeType.PESSIMISTIC_WRITE);
								product.setAllocatedStock(product
										.getAllocatedStock()
										- (orderItem.getQuantity() - orderItem
												.getShippedQuantity()));
							}
						}
					}
					order.setIsAllocatedStock(false);
				}
			}
			
			
		}
		return orders;
	}

	@Override
	public List<Order> findByPaymentStatus(PaymentStatus paymentStatus,
			boolean isSelectedPhone) {
		if (paymentStatus == null) {
			return null;
		}
		String jpql = "select orders from Order orders where  orders.paymentStatus = :paymentStatus";
		if (isSelectedPhone) {// 只查询选号码的订单
			jpql = "select orders from Order orders where  orders.paymentStatus = :paymentStatus and orders.selectedPhone is not null";
		}
		return entityManager.createQuery(jpql, Order.class)
				.setFlushMode(FlushModeType.COMMIT)
				.setParameter("paymentStatus", paymentStatus).getResultList();
	}

	@Override
	public Page<Order> findPageByOrderSnList(Member member,
			List<String> snList, Pageable pageable) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions,
				root.get("sn").in(snList));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		return super.findPage(criteriaQuery, pageable);
	}

	@Override
	public BigDecimal getTotalConsume(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<BigDecimal> criteriaQuery = criteriaBuilder
				.createQuery(BigDecimal.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(criteriaBuilder.sum(root
				.<BigDecimal> get("amountPaid")));
		Predicate restrictions = criteriaBuilder.conjunction();
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.cancelled));
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		restrictions = criteriaBuilder.or(restrictions, criteriaBuilder.equal(
				root.get("paymentStatus"), PaymentStatus.paid));
		restrictions = criteriaBuilder.or(restrictions, criteriaBuilder.equal(
				root.get("paymentStatus"), PaymentStatus.partialPayment));
		restrictions = criteriaBuilder.or(restrictions, criteriaBuilder.equal(
				root.get("paymentStatus"), PaymentStatus.partialRefunds));
		criteriaQuery.where(restrictions);
		return entityManager.createQuery(criteriaQuery)
				.setFlushMode(FlushModeType.COMMIT).getSingleResult();
	}

	/**
	 * 等待收货订单数
	 */
	@Override
	public Long waitingReceiveOrderCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("paymentStatus"), PaymentStatus.paid));// 已经支付
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.cancelled));// 未取消
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.completed));// 未完成
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("shippingStatus"), ShippingStatus.shipped));// 已经发货
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	/**
	 * 已完成订单数
	 */
	@Override
	public Long finishOrderCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("orderStatus"), OrderStatus.completed));
		criteriaQuery.where(restrictions);
		return super.count(criteriaQuery, null);
	}

	/**
	 * 已取消订单数(包括已经过期或者已经取消的订单)
	 */
	@Override
	public Long cancelOrderCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		// 订单未完成未取消的前提下:支付状态为未支付或者部分支付且过期日期不能为空且已经过期

		// 订单未完成未取消的前提
//		restrictions = criteriaBuilder.and(criteriaBuilder.notEqual(
//				root.get("orderStatus"), OrderStatus.cancelled),
//				criteriaBuilder.notEqual(root.get("orderStatus"),
//						OrderStatus.completed));

		// 过期
//		restrictions = criteriaBuilder
//				.and(restrictions, criteriaBuilder.lessThan(
//						root.<Date> get("expire"), new Date()),
//						root.get("expire").isNotNull());

		// 部分支付或者未支付
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.or(
				criteriaBuilder.equal(root.get("paymentStatus"),
						PaymentStatus.partialPayment), criteriaBuilder.equal(
						root.get("paymentStatus"), PaymentStatus.unpaid)));

		// 或者订单状态为取消状态
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.equal(
				root.get("orderStatus"), OrderStatus.cancelled));

		// 会员
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);

		return super.count(criteriaQuery, null);
	}

	@Override
	public Long expiredOrderCount(Member member) {
		CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
		CriteriaQuery<Order> criteriaQuery = criteriaBuilder
				.createQuery(Order.class);
		Root<Order> root = criteriaQuery.from(Order.class);
		criteriaQuery.select(root);
		Predicate restrictions = criteriaBuilder.conjunction();

		restrictions = criteriaBuilder.and(restrictions,criteriaBuilder.or(
				criteriaBuilder.equal(root.get("paymentStatus"),PaymentStatus.unpaid),
				criteriaBuilder.equal(root.get("paymentStatus"), PaymentStatus.partialPayment)
																			)
											);//没支付或者部分支付
		
		
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.lessThan(root.<Date> get("expire"), new Date()));//已过期 
		restrictions = criteriaBuilder.and(restrictions, criteriaBuilder
				.notEqual(root.get("orderStatus"), OrderStatus.cancelled));

		// 会员
		if (member != null) {
			restrictions = criteriaBuilder.and(restrictions,
					criteriaBuilder.equal(root.get("member"), member));
		}
		criteriaQuery.where(restrictions);
		Long i = super.count(criteriaQuery, null);

		return super.count(criteriaQuery, null);
	}

	@Override
	public List<Order> findPage(Member member, Integer status) {
		if (member == null) {
			return null;
		}
		try {
			CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
			CriteriaQuery<Order> criteriaQuery = criteriaBuilder
					.createQuery(Order.class);
			Root<Order> root = criteriaQuery.from(Order.class);
			criteriaQuery.select(root);
			Predicate restrictions = criteriaBuilder.conjunction();
			restrictions = criteriaBuilder
					.and(restrictions, criteriaBuilder.equal(
							root.get("member"), member));
			if(status==1){ //已关闭订单
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("paymentStatus"), PaymentStatus.unpaid));
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("orderStatus"), OrderStatus.unconfirmed));
				//小于过期日期
				//restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThan(root.<Date> get("expire"), new Date()));
			}else if(status==2 || status == 3){
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("paymentStatus"), PaymentStatus.paid));
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("orderStatus"), OrderStatus.unconfirmed));
				if(status==2){
					restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.greaterThan(root.<Date> get("goDate"), new Date()));
				}else{
					restrictions = criteriaBuilder.and(restrictions, criteriaBuilder.lessThanOrEqualTo(root.<Date> get("goDate"), new Date()));
				}
			}else if(status==4){
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("paymentStatus"), PaymentStatus.paid));
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("orderStatus"), OrderStatus.completed));
			}else if(status==5){
				restrictions = criteriaBuilder
						.and(restrictions, criteriaBuilder.equal(
								root.get("orderStatus"), OrderStatus.cancelled));
			}
			restrictions = criteriaBuilder.and(restrictions,criteriaBuilder.equal(
					root.get("isEffective"), true));
			criteriaQuery.where(restrictions);
			
			Pageable pageable =new Pageable();
			pageable.setPageNumber(1);
			pageable.setPageSize(100);
			Page<Order> orders =super.findPage(criteriaQuery, pageable);
//			if(status==3){
////				List<Order> tempOrders = new ArrayList<Order>();
////				if(orders.getContent()!=null && orders.getContent().size()>0){
////					for(int i = 0 ; i< orders.getContent().size() ; i++){
////						Order o = orders.getContent().get(i);
////						if(o.getOrderItems().get(0).getProduct().getBeginDate().getTime() <= new Date().getTime()){
////							tempOrders.add(o);
////						}
////					}
////				}
////				return tempOrders;
//			}else{
				return orders.getContent();
//			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}

	@Override
	public void updateOrderNopaid() {
		try {
			String deleteSql = "update Order o set o.orderStatus = ?  where o.paymentStatus = ? and o.expire  <  ?";
			entityManager.createQuery(deleteSql).setFlushMode(FlushModeType.COMMIT)
			 .setParameter(1, OrderStatus.cancelled).setParameter(2, PaymentStatus.unpaid).setParameter(3, new Date()).executeUpdate();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}